import { defineStore } from "pinia";
import { showNotify } from "vant";
import router from "@/router";
import { addCart, getCartList, updateChecked, updateNum } from "@/api/cart";
import type { AddCartParams } from "@/api/cart";
import { useUserStore } from "./user";

export interface CartItem {
  cartid: string;
  userid: string;
  num: number;
  flag: boolean;
  img1: string;
  proname: string;
  originprice: number;
  proid: string;
  discount: number;
}

export interface IState {
  list: CartItem[];
}

export const useCartStore = defineStore("cart", {
  // state 类型 1
  // state() {
  //   return {
  //     list: [] as CartItem[], // 购物车数据
  //   };
  // },

  // state 类型 2
  state: (): IState => {
    return {
      list: [],
    };
  },

  getters: {
    /**
     * 合计的总价
     *  1. 勾选的商品
     *  2. 累加 数量 * 价格
     */
    total(state) {
      // 获取勾选的数据集合
      let checkedList = state.list.filter((item) => item.flag);
      // 使用 reduce 做累加
      let total = checkedList.reduce((total, item) => {
        return (total += item.originprice * item.num);
      }, 0);
      // 组件需要的是分的单位
      return total * 100;
    },

    /**
     * 是否全选
     *   1.
     */
    isAll(state) {
      // 数组中每一项是否都满足条件
      if (state.list.length) {
        return state.list.every((item) => item.flag);
      } else {
        return false;
      }
    },
  },

  actions: {
    async add(data: AddCartParams) {
      // 调用接口
      await addCart(data);
      // 成功提示
      showNotify({
        type: "success",
        duration: 1000,
        message: "加入成功",
        onClose: () => {
          // 跳转到购物车页面
          router.push({ name: "cart" });
        },
      });
    },

    /**
     * 获取购物车列表数据
     */
    async getList() {
      // 组合式函数一般只能在setup入口的顶级调用，原因是这个组合式函数与组件需要建立联系，好在组件销毁时，将组合式函数中写的
      // 一些全局绑定的事件也能销毁

      // pinia 的 store 的组合式函数，它返回的实例对象中就是一些数据和方法，它内部也没有需要根组件强关联的事件
      const userStore = useUserStore();
      const response = await getCartList(userStore.userid);
      this.list = response.data;
    },

    /**
     * 更新某个商品的勾选状态
     * @param cartid 购物车商品Id
     * @param flag 状态
     */
    async setChecked(cartid: string, flag: boolean) {
      // 调用接口修改数据
      await updateChecked(cartid, flag);
      // 1. 让页面更新的方式 - 重新获取下列表数据
      // this.getList();
      // 2. 让页面更新的方式 - 直接修改对应的数据中的 flag 的值
      //      1. 获取对应数据的下标
      const index = this.list.findIndex((item) => item.cartid === cartid);
      //      2. 直接修改对应下标的数据
      this.list[index].flag = flag;
    },

    async setNum(cartid: string, num: number) {
      // 调用接口修改数据
      await updateNum(cartid, num);
      // 发现不更新 this.list 中对应的 数据的 num 也OK，原因是什么？
      //    受控与非受控
      //      1. 获取对应数据的下标
      const index = this.list.findIndex((item) => item.cartid === cartid);
      //      2. 直接修改对应下标的数据
      this.list[index].num = num;
    },
  },
});
